package com.nowcoder.community.controller;

import com.alibaba.fastjson.JSONObject;
import com.nowcoder.community.annotation.LoginRequired;
import com.nowcoder.community.entity.Message;
import com.nowcoder.community.entity.Page;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.service.MessageService;
import com.nowcoder.community.service.UserService;
import com.nowcoder.community.util.CommunityConstant;
import com.nowcoder.community.util.CommunityUtil;
import com.nowcoder.community.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.util.HtmlUtils;

import javax.print.attribute.standard.JobKOctets;
import java.util.*;

@Controller
public class MessageController implements CommunityConstant {

    @Autowired
    private MessageService messageService;

    @Autowired
    private UserService userService;

    @Autowired
    private HostHolder hostHolder;

    @LoginRequired
    @RequestMapping(path = "/letter/list", method = RequestMethod.GET)
    public String getConversationList(Model model, Page page) {
        User user = hostHolder.getUsers();
        // 设置分页组件信息
        page.setRows(messageService.findConversationCount(user.getId()));
        page.setLimit(5);
        page.setPath("/letter/list");

        List<Message> list = messageService.findConversations(
                user.getId(), page.getOffSet(), page.getLimit());
        List<HashMap<String, Object>> conversationList = new ArrayList<>();
        if(list != null && !list.isEmpty()) {
            for(Message conversation : list) {
                HashMap<String, Object> map = new HashMap<>();
                map.put("conversation", conversation);
                // 查询会话下一共有多少条私信
                map.put("letterCount", messageService.findLetterCount(
                        conversation.getConversationId())
                );
                // 查询会话下未读私信的数量
                map.put("unreadCount", messageService.findLetterUnreadCount(
                        user.getId(), conversation.getConversationId())
                );
                // 显示消息发送方用户 --> 用于初始化用户头像
                int targetId = user.getId() == conversation.getFromId() ? conversation.getToId() : conversation.getFromId();
                map.put("target", userService.findUserById(targetId));
                conversationList.add(map);
            }
        }
        model.addAttribute("conversations", conversationList);
        // 查询该用户所有未读消息的数量
        model.addAttribute("unreadLetterCount", messageService.findLetterUnreadCount(user.getId(), null));

        int noticeUnreadCount = messageService.findNoticeUnreadCount(user.getId(), null);
        model.addAttribute("noticeUnreadCount", noticeUnreadCount);

        return "/site/letter";
    }

    private List<Integer> getLetterIds(List<Message> letterList, User user) {
        List<Integer> unreadList = new ArrayList<>();
        for(Message letter : letterList) {
            // 消息状态为未读
            // 且消息的接收者确实为当前登录用户
            if(letter.getStatus() == 0 && user.getId() == letter.getToId()) {
                unreadList.add(letter.getId());
            }
        }
        return unreadList;
    }

    @LoginRequired
    @RequestMapping(value = "/letter/detail/{conversationId}", method = RequestMethod.GET)
    public String getUnreadLetterDetail(@PathVariable String conversationId, Model model, Page page) {
        User user = hostHolder.getUsers();

        page.setRows(messageService.findLetterCount(conversationId));
        page.setLimit(5);
        page.setPath("/letter/detail/" + conversationId);

        // 会话的私信列表
        List<Message> letterList = messageService.findLetters(conversationId, page.getOffSet(), page.getLimit());
        List<HashMap<String, Object>> letters = new ArrayList<>();
        if(letterList != null && !letterList.isEmpty()) {
            for(Message letter : letterList) {
                HashMap<String, Object> map = new HashMap<>();
                map.put("letter", letter);
                // 为了渲染消息发出者的头像
                map.put("fromUser", userService.findUserById(letter.getFromId()));
                letters.add(map);
            }
            // 获取当前用户在本会话中的未读消息集合
            List<Integer> unreadLetterIds = getLetterIds(letterList, user);
            // 将未读消息设置为已读
            if(!unreadLetterIds.isEmpty()) {
                messageService.readMessage(unreadLetterIds);
            }
        }
        model.addAttribute("letters", letters);

        // 获取:
        // 相对于当前登录用户,本会话的对家聊天人
        String[] ids = conversationId.split("_");
        int idFront = Integer.parseInt(ids[0]), idLast = Integer.parseInt(ids[1]);
        int targetId = user.getId() == idFront ? idLast : idFront;
        model.addAttribute("sender", userService.findUserById(targetId));

        return "/site/letter-detail";
    }

    private String generateConversationId(int targetUserId, int sendUserId) {
        int firstId = Math.min(targetUserId, sendUserId);
        int secondId = Math.max(targetUserId, sendUserId);
        return firstId + "_" + secondId;
    }

    /**
     * 异步请求注解 @ResponseBody
     * @param toName
     * @return
     */
    @LoginRequired
    @RequestMapping(path = "/letter/send", method = RequestMethod.POST)
    @ResponseBody
    public String sendLetter(String toName, String content) {
        User targetUser = userService.findUserByName(toName);
        if(targetUser == null) {
            return CommunityUtil.getJsonString(1, "目标用户不存在");
        }
        User sendUser = hostHolder.getUsers();
        Message message = new Message();
        message.setFromId(sendUser.getId());
        message.setToId(targetUser.getId());
        message.setContent(content);
        message.setConversationId(generateConversationId(targetUser.getId(), sendUser.getId()));
        message.setCreateTime(new Date());
        messageService.addMessage(message);
        return CommunityUtil.getJsonString(0);
    }

    @RequestMapping(path = "/notice/list", method = RequestMethod.GET)
    public String getNoticeList(Model model) {
        User user = hostHolder.getUsers();

        // 查询评论类的最新一条通知
        Message commentMsg = messageService.findLatestNotice(user.getId(), TOPIC_COMMENT);
        if(commentMsg != null) {
            Map<String, Object> commentMsgVO = new HashMap<>();
            commentMsgVO.put("message", commentMsg);
            // 将由于存储在数据库中而发生变化的一些字符转义回来
            String content = HtmlUtils.htmlUnescape(commentMsg.getContent());
            // 在EventConsumer中是将一个HashMap转化成了JSON字符串
            // 现在转化回来需要指定HashMap.class
            // 转化结果得到一个HashMap对象
            HashMap<String, Object> data = JSONObject.parseObject(content, HashMap.class);
            commentMsgVO.put("user", userService.findUserById((Integer) data.get("userId")));
            commentMsgVO.put("entityType", data.get("entityType"));
            commentMsgVO.put("entityId", data.get("entityId"));
            commentMsgVO.put("postId", data.get("discussPostId"));

            int noticeCount = messageService.findNoticeCount(user.getId(), TOPIC_COMMENT);
            int noticeUnreadCount = messageService.findNoticeUnreadCount(user.getId(), TOPIC_COMMENT);
            commentMsgVO.put("noticeCount", noticeCount);
            commentMsgVO.put("noticeUnreadCount", noticeUnreadCount);
            model.addAttribute("commentNotice", commentMsgVO);
        }


        // 查询点赞类的最新一条通知
        Message likeMsg = messageService.findLatestNotice(user.getId(), TOPIC_LIKE);
        if(likeMsg != null) {
            Map<String, Object> likeMsgVO = new HashMap<>();
            likeMsgVO.put("message", likeMsg);
            String content = HtmlUtils.htmlUnescape(likeMsg.getContent());

            HashMap<String, Object> data = JSONObject.parseObject(content, HashMap.class);

            likeMsgVO.put("user", userService.findUserById((Integer) data.get("userId")));
            likeMsgVO.put("entityType", data.get("entityType"));
            likeMsgVO.put("entityId", data.get("entityId"));
            likeMsgVO.put("postId", data.get("discussPostId"));

            int noticeCount = messageService.findNoticeCount(user.getId(), TOPIC_LIKE);
            int noticeUnreadCount = messageService.findNoticeUnreadCount(user.getId(), TOPIC_LIKE);
            likeMsgVO.put("noticeCount", noticeCount);
            likeMsgVO.put("noticeUnreadCount", noticeUnreadCount);
            model.addAttribute("likeNotice", likeMsgVO);
        }

        // 查询关注类的最新一条通知
        Message followMsg = messageService.findLatestNotice(user.getId(), TOPIC_FOLLOW);
        if(followMsg != null) {
            Map<String, Object> followMsgVO = new HashMap<>();
            followMsgVO.put("message", followMsg);

            String content = HtmlUtils.htmlUnescape(followMsg.getContent());

            Map<String, Object> data = JSONObject.parseObject(content, HashMap.class);
            followMsgVO.put("user", userService.findUserById((Integer) data.get("userId")));
            followMsgVO.put("entityType", data.get("entityType"));
            followMsgVO.put("entityId", data.get("entityId"));
            // followMsgVO.put("targetUserId", data.get("targetUserId"));

            int noticeCount = messageService.findNoticeCount(user.getId(), TOPIC_FOLLOW);
            int noticeUnreadCount = messageService.findNoticeUnreadCount(user.getId(), TOPIC_FOLLOW);
            followMsgVO.put("noticeCount", noticeCount);
            followMsgVO.put("noticeUnreadCount", noticeUnreadCount);

            model.addAttribute("followNotice", followMsgVO);
        }

        // 查询一下总的: 1.私信未读数量; 2.系统消息未读数量
        // 用于前端页面的显示
        int letterUnreadCount = messageService.findLetterUnreadCount(user.getId(), null);
        int noticeUnreadCount = messageService.findNoticeUnreadCount(user.getId(), null);
        model.addAttribute("letterUnreadCount", letterUnreadCount);
        model.addAttribute("noticeUnreadCount", noticeUnreadCount);

        return "/site/notice";
    }


    @RequestMapping(path = "/notice/detail/{topic}", method = RequestMethod.GET)
    public String getNoticeDetail(@PathVariable("topic") String topic, Page page, Model model) {
        User user = hostHolder.getUsers();
        page.setLimit(5);
        page.setPath("/notice/detail/" + topic);
        page.setRows(messageService.findNoticeCount(user.getId(), topic));

        List<Message> noticeList = messageService.findNotices(user.getId(), topic, page.getOffSet(), page.getLimit());
        List<Map<String, Object>> noticeVoList = new ArrayList<>();
        if(noticeList != null && !noticeList.isEmpty()) {
            for(Message notice : noticeList) {
                Map<String, Object> map = new HashMap<>();
                map.put("notice", notice);

                String content = HtmlUtils.htmlUnescape(notice.getContent());
                Map<String, Object> data = JSONObject.parseObject(content, HashMap.class);
                map.put("user", userService.findUserById((int) data.get("userId")));
                map.put("entityType", data.get("entityType"));
                map.put("entityId", data.get("entityId"));
                map.put("postId", data.get("discussPostId"));

                // 通知作者
                map.put("fromUser", userService.findUserById(notice.getFromId()));

                noticeVoList.add(map);
            }
        }
        model.addAttribute("notices", noticeVoList);
        model.addAttribute("topic", topic);

        // 设置一些消息已读
        List<Integer> ids = getLetterIds(noticeList, user);
        if(!ids.isEmpty()) {
            messageService.readMessage(ids);
        }

        return "/site/notice-detail";
    }

}
